<template>
  <br>
  <el-row justify="center">
    <el-col :span="5">
      <h3>文档目录
        <el-button size="small" circle
                   @click="addDoc()"
                   title="增加文档">
          <el-icon>
            <Plus/>
          </el-icon>
        </el-button>
      </h3>
      <el-row>
        <!-- 文档目录管理 -->
        <el-tree
            :data="chaps"
            :props="defaultProps"
            ref="docMenu"
            draggable
            :expand-on-click-node="false"
            node-key="id"
            @node-drag-end="handleDocMenuDragEnd">
          <template #default="{ node, data }">
            <el-row justify="start" class="docRow" align="middle">
              <el-col :span="19" style="font-size: 16px;flex:0;color: #2156a5;"
                      @click="docMenuChange(data)"
                      :title="data.desc">
                <span>{{ data.menuName }}</span>
              </el-col>
              <el-col :span="3" :offset="2">
                <el-switch @change="enableDocMenu(data)" class="docMenuSwitch"
                           size="small"
                           v-model="data.enableFlag"
                           :active-value="1"
                           :inactive-value="0"
                           active-text="启"
                           inactive-text="停">
                </el-switch>

                <el-button style="padding: 0 8px" text @click="editDocMenu(data)">
                  <el-icon>
                    <Edit/>
                  </el-icon>
                </el-button>
              </el-col>
            </el-row>
          </template>

        </el-tree>
      </el-row>
    </el-col>

    <!-- 接口目录管理 -->
    <el-col :span="12">
      <!-- 标题 -->
      <h4>{{ apiDocTitle }}
        <el-button circle size="small" title="增加目录" @click="addApiMenu()">
          <el-icon>
            <Plus/>
          </el-icon>
        </el-button>
      </h4>
      点击名称可修改，筛选：
      <el-input style="width: 200px" size="small"
                placeholder="输入关键字进行过滤"
                clearable
                v-model="filterText"/>
      <!-- 数据展示 -->
      <el-row justify="start">
        <el-col :offset="1" :span="23">
          <el-tree style="width: 100%"
                   :props="defaultProps"
                   :data="apiMenus"
                   ref="apiMenuTree"
                   :filter-node-method="filterApi"
                   :expand-on-click-node="false"
                   draggable node-key="id"
                   @node-drag-end="handleDragApiEnd">
            <template #default="{ node, data }">
              <!-- 图片 -->
              <span class="apiMenuRow">
                <el-icon v-if="data.menuType===0">
                  <Folder/>
                </el-icon>
                <el-icon v-if="data.menuType===1">
                  <Phone/>
                </el-icon>
              </span>

              <!-- 操作 -->
              <span class="apiMenuRow">
                <el-switch size="small" @change="enableDocMenu(data)"
                           v-model="data.enableFlag"
                           :active-value="1"
                           :inactive-value="0"
                           active-text="启"
                           inactive-text="停">
                </el-switch>
              </span>

              <!-- 目录名称 -->
              <span class="apiMenuRow" :title="data.desc"
                    v-if="data.menuType === 0">
                <!-- 增加下级 -->
                <el-button size="small" circle text
                           @click="addApiMenu(data)"
                           title="增加下级">
                  <el-icon>
                    <Plus/>
                  </el-icon>
                </el-button>
                <span class="apiMenuRow" @click="updateApiMenu(data)">
                  {{ data.menuName }}
                </span>
              </span>
              <!-- 接口信息 -->
              <span class="apiMenuRow" v-else>
                <span class="apiMenuRow" v-if="data.apiId">
                  <span class="apiMenuRow" :title="data.apiDesc"
                        @click="updateApiMenu(data)"
                        v-if="data.menuType === 1">
                    {{ data.apiName }}
                  </span>
                  <span class="apiMenuRow" @click="updateApiMenu(data)">
                    {{ data.apiType }}
                  </span>
                  <span class="apiMenuRow" :title="data.apiDesc">
                    {{ data.apiUri }}
                  <el-button @click="cpText(data.apiUri)" text style="padding: 0;!important;">
                    <el-icon><DocumentCopy/></el-icon>
                  </el-button>
                  </span>
                  <span class="apiMenuRow" v-if="data.serverName" :title="data.serverDesc">
                    {{ data.serverName }}
                  </span>
                </span>
                <span class="apiMenuRow" v-else>
                  {{ data.menuName }}
                </span>
              </span>
            </template>

          </el-tree>
        </el-col>
      </el-row>
    </el-col>
  </el-row>

  <!-- 文档目录编辑 -->
  <el-dialog
      :title="docTitle"
      v-model="docVisible"
      width="40%">
    <el-row align="middle" justify="center">
      <el-col :span="20">

        <el-form ref="docMenuForm" :model="docMenu" :rules="docRules">
          <el-form-item label="文档名称：" prop="menuName">
            <el-input v-model="docMenu.menuName" show-word-limit
                      :maxlength="docMenuNameMax" type="text"></el-input>
          </el-form-item>

          <el-form-item label="文档说明：" prop="desc">
            <el-input v-model="docMenu.desc" show-word-limit
                      maxlength="255" type="textarea"></el-input>
          </el-form-item>

          <el-form-item label="文档启停：">
            <el-switch size="small"
                       v-model="docMenu.enableFlag"
                       :active-value="1"
                       :inactive-value="0"
                       active-text="启"
                       inactive-text="停">
            </el-switch>
          </el-form-item>

          <el-form-item label="修改时间：">
            <el-date-picker disabled
                            v-model="docMenu.updateTime"
                            type="datetime"
                            placeholder="修改时间"/>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <template #footer>
    <span class="dialog-footer">
      <el-button @click="docVisible = false">取 消</el-button>
      <el-button type="primary" @click="setDocMenu()">确 定</el-button>
    </span>
    </template>
  </el-dialog>

  <!-- 接口目录编辑 -->
  <el-dialog
      :title="apiTitle"
      v-model="apiVisible"
      width="40%">
    <el-row align="middle" justify="center">
      <el-col :span="20">

        <el-form ref="apiMenuForm" :model="apiMenu" :rules="apiRules">
          <el-form-item label="目录名称：" prop="menuName">
            <el-input v-model="apiMenu.menuName" show-word-limit title="目录名称"
                      :maxlength="docMenuNameMax" type="text"></el-input>
          </el-form-item>

          <el-form-item label="目录说明：" prop="desc">
            <el-input v-model="apiMenu.desc" show-word-limit title="目录说明"
                      maxlength="255" type="textarea"></el-input>
          </el-form-item>

          <el-form-item label=" 目录启停：">
            <el-switch size="small"
                       v-model="apiMenu.enableFlag"
                       :active-value="1"
                       :inactive-value="0"
                       active-text="启"
                       inactive-text="停">
            </el-switch>
          </el-form-item>

          <el-form-item label=" 数据类型：">
            <el-switch size="small"
                       v-model="apiMenu.menuType"
                       :active-value="1"
                       :inactive-value="0"
                       inactive-color="#13ce66"
                       active-text="接口"
                       inactive-text="目录">
            </el-switch>
          </el-form-item>

          <div v-if="apiMenu.menuType === 1">
            <el-form-item label=" 关联接口：">
              <!-- 变更接口 -->
              <el-select v-model="apiMenu.apiId" filterable size="small"
                         @change="apiChange" placeholder="Select">
                <el-option :title="item.apiUri"
                           v-for="item in allApi"
                           :key="item.id"
                           :label="item.apiName + '(' + item.apiType + ' ' + item.apiUri + ')'"
                           :value="item.id"/>
              </el-select>
            </el-form-item>

            <div v-if="apiMenu.apiId">
              <el-form-item label="接口名称：" prop="apiName">
                <el-input type="text" v-model="apiMenu.apiName"
                          show-word-limit title="接口名称" :maxlength="docMenuNameMax"/>
              </el-form-item>

              <el-form-item label="接口说明：" prop="desc">
                <el-input v-model="apiMenu.apiDesc" show-word-limit title="接口说明"
                          maxlength="255" type="textarea"></el-input>
              </el-form-item>

              <el-form-item label=" 生命周期：" prop="desc">
                <el-radio-group v-model="apiMenu.stateId" label="size control" size="small">
                  <el-radio-button :label="apiState.id" v-for="apiState in apiStates" :title="apiState.stateDesc">
                    {{ apiState.stateName }}
                  </el-radio-button>
                </el-radio-group>
              </el-form-item>

              <el-form-item label=" 接口信息：">
                <span class="apiMenuRow">{{ apiMenu.apiType }}</span>
                <span class="apiMenuRow">{{ apiMenu.apiUri }}
                  <el-button @click="cpText(apiMenu.apiUri)" text style="padding: 0;!important;">
                    <el-icon><DocumentCopy/></el-icon>
                  </el-button>
                </span>
              </el-form-item>
            </div>
          </div>

          <el-form-item label=" 修改时间：">
            <el-date-picker disabled
                            v-model="apiMenu.updateTime"
                            type="datetime"
                            placeholder="修改时间"/>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <template #footer>
    <span class="dialog-footer">
      <el-button @click="apiVisible = false">取 消</el-button>
      <el-button type="primary" @click="upsertApiMenuDo()">确 定</el-button>
    </span>
    </template>
  </el-dialog>
</template>

<script>
import axios from "@/plugins/myaxios";
import {Edit, Folder, Phone, Plus, DocumentCopy} from '@element-plus/icons-vue'
import ApiDocManageConstants from '@/utils/api-utils/ApiDocManageConstants'
import {ElMessage} from "element-plus";
import CommonUtils from '@/utils/CommonUtils'

export default {
  name: "ApiDocManage",
  components: {Plus, Edit, Folder, Phone, DocumentCopy},
  data() {
    return {
      chaps: [],
      defaultProps: {
        children: 'children',
        label: 'menuName'
      },
      docTitle: '修改目录',
      docVisible: false,
      docMenu: {},
      docMenuNameMax: 15,
      docRules: {
        menuName: [
          {required: true, message: '请输入文档名称', trigger: 'blur'},
          {min: 2, message: '长度不少于 2 个字符', trigger: 'blur'}
        ],
        desc: [
          {required: true, message: '请输入文档说明', trigger: 'blur'},
          {min: 2, max: 255, message: '长度在 2 到 255 个字符', trigger: 'blur'}
        ],
      },
      apiDocTitle: '测试',
      apiMenus: [],
      allApi: [],
      apiMenu: {},
      apiInfo: {},
      apiTitle: '',
      apiVisible: false,
      apiRules: {
        menuName: [
          {required: true, message: '请输入目录名称', trigger: 'blur'},
          {min: 2, message: '长度不少于 2 个字符', trigger: 'blur'}
        ],
        apiName: [
          {required: true, message: '请输入接口名称', trigger: 'blur'},
          {min: 2, message: '长度不少于 2 个字符', trigger: 'blur'}
        ],
        desc: [
          {required: true, message: '请输入接口目录说明', trigger: 'blur'},
          {min: 2, max: 255, message: '长度在 2 到 255 个字符', trigger: 'blur'}
        ],
      },
      apiStates: [],
      nodeOp: {},
      filterText: ''
    }
  },
  methods: {
    getDocChap() {
      let that = this
      axios.get("/dist/docMenu/getDocChap").then(req => {
        that.chaps = req.data
        that.apiDocTitle = that.chaps[0].menuName
        that.docMenu = that.chaps[0]
        that.getChildrenById(that.chaps[0].id)
      })
    },
    addDoc() {
      this.docTitle = '增加文档'
      this.docVisible = true
      this.docMenu = ApiDocManageConstants.getMenuObj()
      // this.submitForm('docMenuForm')
    },
    handleDocMenuDragEnd(draggingNode, dropNode, dropType, ev) {
      if (draggingNode.data.id === dropNode.data.id) {
        console.log('自己');
        return
      }
      if (dropType !== 'inner') {
        // 调整顺序
        console.log('set order')
        if (dropType === 'before') {
          this.setOrder(draggingNode.data.id, dropNode.data.id, 0)
        } else {
          this.setOrder(draggingNode.data.id, dropNode.data.id, 1)
        }
      } else {
        // 调整树结构
        console.log('set parent')
      }
    },
    docMenuChange(data) {
      this.apiDocTitle = data.menuName
      this.getChildrenById(data.id)
    },
    enableDocMenu(data) {
      let _this = this
      let docMenu = {enableFlag: data.enableFlag, id: data.id}
      axios.put("/dist/docMenu/", docMenu).then(req => {
        ElMessage.success('修改成功。')
        _this.getDocChap()
      }, err => {
        ElMessage.error('修改失败。')
      })
    },
    editDocMenu(data) {
      this.docTitle = '修改文档'
      this.docMenu = data
      this.docVisible = true
    },
    setDocMenu() {
      let _this = this
      this.$refs['docMenuForm'].validate((valid) => {
        if (!valid) {
          ElMessage.error("数据不规范，请修改后再操作")
        } else {
          axios.put("/dist/docMenu/", this.docMenu).then(req => {
            ElMessage.success(_this.docTitle + '成功。')
            _this.docVisible = false
            _this.getDocChap()
          }, err => {
            ElMessage.error(_this.docTitle + '失败。')
          })
        }
      });
    },
    getChildrenById(id) {
      this.findAllApiNoRlt(id)
      let _this = this
      axios.get("/dist/docMenu/queryChildListById/" + id).then(req => {
        _this.apiMenus = req.data
      }, err => {
        ElMessage.error('查询文档目录失败。')
      })
    },
    filterApi(value, data) {
      console.log('value', value);
      console.log('data', data);
      if (!value) return true
      return (data.menuName && data.menuName.indexOf(value) !== -1) ||
          (data.apiUri && data.apiUri.indexOf(value) !== -1) ||
          (data.apiName && data.apiName.indexOf(value) !== -1)
    },
    handleDragApiEnd(draggingNode, dropNode, dropType, ev) {
      if (draggingNode.data.id === dropNode.data.id) {
        console.log('自己');
        return
      }
      if (dropType !== 'inner') {
        // 调整顺序
        console.log('set order')
        if (dropType === 'before') {
          this.setOrder(draggingNode.data.id, dropNode.data.id, 0)
        } else {
          this.setOrder(draggingNode.data.id, dropNode.data.id, 1)
        }
      } else {
        // 调整树结构
        console.log('set parent')
        this.setParent(draggingNode, dropNode)
      }
    },
    setParent(draggingNode, dropNode) {
      draggingNode.data.parentId = dropNode.data.id
      draggingNode.data.order_num = 9999
      draggingNode.data.idPath = dropNode.data.idPath + "," + dropNode.data.id
      let update = "/dist/docMenu/upsert"
      axios.post(
          update,
          draggingNode.data
      ).then(req => {
        ElMessage.success({
          message: '成功！',
          duration: 1000
        })
        console.log(draggingNode)
        if (!dropNode.data.children) {
          dropNode.data.children = []
        }
        dropNode.data.children.push(draggingNode.data)
        console.log(draggingNode)
      }, err => {
        console.log('移动失败！', err)
        ElMessage.error({
          message: err.data,
          duration: 1500,
        })
      })
    },
    setOrder(nodeDataId, dropNodeId, type) {
      let update = "/dist/docMenu/orderChange"
      axios.post(
          update,
          {
            moveId: nodeDataId,
            dropId: dropNodeId,
            type: type
          }
      ).then(req => {
        ElMessage.success({
          message: '成功！',
          duration: 1000
        })
      }, err => {
        console.log('移动失败！', err)
        ElMessage.error({
          message: err.data,
          duration: 1500,
        })
      })
    },
    findAllApiNoRlt(id) {
      let _this = this
      axios.get("/dist/apiInfo/noRltMenu/" + id).then(req => {
        _this.allApi = req.data
      }, err => {
        ElMessage.error('查询接口信息失败。')
      })
    },
    addApiMenu(apiMenuParent) {
      this.apiMenu = ApiDocManageConstants.getApiMenuObj()
      if (apiMenuParent) {
        console.log('增加下级')
        this.apiTitle = apiMenuParent.menuName + ' 增加下级'
        this.initAddApiMenu(apiMenuParent)
        this.nodeOp = apiMenuParent
      } else {
        console.log('增加顶级')
        this.apiTitle = this.docMenu.menuName + ' 增加目录'
        this.initAddApiMenu(this.docMenu)
        this.nodeOp = {'children': this.apiMenus}
      }
      this.apiVisible = true
    },
    initAddApiMenu(obj) {
      this.apiMenu.parentId = obj.id
      this.apiMenu.idPath = obj.idPath + ',' + obj.id
    },
    updateApiMenu(apiMenu) {
      this.apiMenu = apiMenu
      this.apiVisible = true
      if (apiMenu.apiId) {
        this.apiTitle = apiMenu.apiName + " 接口修改"
      } else {
        this.apiTitle = apiMenu.menuName + " 目录修改"
      }
      console.log('update api menu')
    },
    upsertApiMenuDo() {
      let _this = this
      this.$refs['apiMenuForm'].validate((valid) => {
        if (!valid) {
          ElMessage.error("数据不规范，请修改后再操作")
        } else {
          axios.post("/dist/docMenu/upsert", this.apiMenu).then(req => {
            ElMessage.success('操作成功。')
            _this.docVisible = false
            _this.apiInfo.apiName = _this.apiMenu.apiName
            _this.apiInfo.apiDesc = _this.apiMenu.apiDesc
            _this.apiInfo.stateId = _this.apiMenu.stateId
            _this.apiInfo.apiType = _this.apiMenu.apiType
            _this.apiInfo.apiUri = _this.apiMenu.apiUri
            _this.addChildApi(req.data)
            _this.apiVisible = false
          }, err => {
            ElMessage.error(_this.docTitle + '操作失败。')
          })
        }
      });
    },
    findApiState() {
      let _this = this
      axios.get("/dist/apiStatus/").then(req => {
        _this.apiStates = req.data
      }, err => {
        ElMessage.error('查询生命周期失败。')
      })
    },
    apiChange() {
      for (const apiInfo of this.allApi) {
        if (this.apiMenu.apiId === apiInfo.id) {
          this.apiInfo = apiInfo
          break
        }
      }
      console.log(this.apiInfo)
      this.apiMenu.apiName = this.apiInfo.apiName
      this.apiMenu.apiDesc = this.apiInfo.apiDesc
      this.apiMenu.stateId = this.apiInfo.stateId
      this.apiMenu.apiType = this.apiInfo.apiType
      this.apiMenu.apiUri = this.apiInfo.apiUri
    },
    addChildApi(obj) {
      if (this.nodeOp.children) {
        this.nodeOp.children.push(obj)
      } else {
        console.log('没有子集，增加子集')
        this.nodeOp.children = [obj]
        console.log(this.nodeOp.children);
      }
    },
    cpText(str) {
      CommonUtils.copyTextIn(str)
    }
  },
  mounted() {
    this.getDocChap()
    this.findApiState()
  },
  watch: {
    filterText(val) {
      this.$refs.apiMenuTree.filter(val);
    }
  }
}
</script>

<style scoped>
.docRow {
  margin-top: 2px !important;;
}

.apiMenuRow {
  margin-right: 10px !important;
}

.cpBtn {
  padding: 0 !important;
}
</style>